unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  frfrfr = record
    x, y, num: integer;
    p: TPanel;
  end;
  TForm1 = class(TForm)
    Button1: TButton;
    Timer1: TTimer;
    Edit1: TEdit;
    Label1: TLabel;
    procedure Timer1Timer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Heapify(num: integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  arr: array of frfrfr;
  rrr: array of TPanel;
  step, memory, n: integer;
  flag, off: boolean;

implementation

{$R *.dfm}

procedure TForm1.Heapify(num: integer);
var
  x, a, b: Integer;
begin
  while (1=1) do
  begin
  x := arr[num].num;
  a := 2000000000;
  b := a;
  if (2*num + 1 <= memory) then
    a := arr[2*num+1].num;
  if (2*num  <= memory) then
    b := arr[2*num].num;
  if (a <= b) and (a < x) then
  begin
    arr[num].num := a;
    arr[2*num+1].num := x;
    num := 2*num + 1;
  end else
  if (b <= a) and (b < x) then
  begin
    arr[num].num := b;
    arr[2*num].num := x;
    num := 2*num;
  end else
    break;
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var i: integer;
begin
  if (flag) then
  begin
    Heapify(step);
    if (step=1) then
      flag:= false
    else
      dec(step);
  end else begin
    arr[1].num:= arr[1].num+arr[memory].num;
    arr[memory].num:= arr[1].num-arr[memory].num;
    arr[1].num:= arr[1].num-arr[memory].num;
    dec (memory);
    Heapify (1);
    if (step=n-1) then
      Timer1.Enabled:= false
    else
      inc (step);
  end;

  for i := 1 to n do
  begin
    arr[i].p.Caption:=IntToStr(arr[i].num);
    rrr[i].Caption:=IntToStr(arr[i].num);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i, j, m, a, b, sum, frfr: integer;
begin
  randomize;
  if off then
    for I := 1 to n do
    begin
      arr[i].p.Destroy;
      rrr[i].Destroy;
    end
  else
    off:= true;
  Canvas.Pen.Color:= clWhite;
  Canvas.Rectangle(Form1.ClientRect);

  n:= StrToInt(Edit1.Text);
  m:= 1;
  frfr:= 1;
  repeat
    frfr:= frfr*2;
    inc(m);
  until (n<frfr*2);

  a:= Form1.Width div frfr;
  frfr:= 1;
  sum:= 0;
  Setlength (arr, n);
  setlength (rrr, n);
  for i := 0 to m-1 do
  begin
    b:= (Form1.Width div (frfr*2));
    arr[sum+1].x:= b;
    arr[sum+1].y:= a*i + (a div 2);
    inc (sum);
    while (sum<frfr*2-1) and (sum<N) do
    begin
      arr[sum+1].x:= arr[sum].x +2*b;
      arr[sum+1].y:= arr[sum].y;
      inc(sum);
    end;
    frfr:= frfr*2;
  end;

  for i := 1 to n do
  begin
    Canvas.Pen.Color:= clBlack;
    Canvas.MoveTo(arr[i].x, arr[i].y);
    if (2*i+1<=n) then
      Canvas.LineTo(arr[2*i+1].x, arr[2*i+1].y);
    Canvas.MoveTo(arr[i].x, arr[i].y);
    if (2*i<=n) then
      Canvas.LineTo(arr[2*i].x, arr[2*i].y);
    arr[i].num:= random (n*n)+1;
    arr[i].p:= TPanel.Create(Form1);
    arr[i].p.Parent:= Form1;
    arr[i].p.Width:= 20;
    arr[i].p.Height:= 20;
    arr[i].p.Left:= arr[i].x-10;
    arr[i].p.Top:= arr[i].y-10;
    arr[i].p.Caption:= IntToStr(arr[i].num);
    rrr[i]:= TPanel.Create(Form1);
    rrr[i].Parent:= Form1;
    if (Form1.ClientWidth div n>50) then
    begin
      rrr[i].Width:= 50;
      rrr[i].Height:= 50;
    end else begin
      rrr[i].Width:= Form1.ClientWidth div n;
      rrr[i].Height:= rrr[i].Width;
    end;
    rrr[i].Left:= (i-1)*rrr[i].Width;
    rrr[i].Top:= Form1.ClientHeight-rrr[i].Height;
    rrr[i].Caption:= IntToStr(arr[i].num);
  end;
  step:= n;
  memory:= n;
  flag:= true;
  Timer1.Enabled:= true;
end;
end.

